// stdafx.h : include file for standard system include files,
//      or project specific include files that are used frequently,
//      but are changed infrequently

#if !defined(AFX_STDAFX_H__893CD0F1_19C4_11D3_ABA0_00C04F6BC74E__INCLUDED_)
#define AFX_STDAFX_H__893CD0F1_19C4_11D3_ABA0_00C04F6BC74E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED

#include <atlbase.h>  // Just to pick up the standard includes, not used except for conv.
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module

extern volatile ULONG g_cObj;
extern volatile ULONG g_cLock;
#define ADD_OBJECT InterlockedIncrement((long*)&g_cObj)
#define REMOVE_OBJECT InterlockedDecrement((long*)&g_cObj)
#define LOCK_SERVER InterlockedIncrement((long*)&g_cLock)
#define UNLOCK_SERVER InterlockedDecrement((long*)&g_cLock)

#define IIDOK(A) IsEqualIID(riid, IID_##A)  //eg: IIDOK(IUnknown)

#define DIM(X) (sizeof(X) / (sizeof((X)[0])))

#include "CFBase.h"

template<class I>
class _declspec(novtable) CBaseUnk : public I
{
public:
    CBaseUnk() : m_dwRefs(0){ADD_OBJECT;}

    virtual ~CBaseUnk(){REMOVE_OBJECT;}

    HRESULT _BaseQI(REFIID riid, void** ppvObj)
    {
        if (IIDOK(IUnknown) || IsEqualIID(riid, __uuidof(I)))
        {
            m_dwRefs++;
            *ppvObj = (IUnknown*)(I*)this;
            return NOERROR;
        }
        return E_NOINTERFACE;
    }
    ULONG _BaseAddRef(){return ++m_dwRefs;}
    ULONG _BaseRelease(){return (0 == --m_dwRefs) ? delete this, 0 : m_dwRefs;}
protected:
    DWORD m_dwRefs;
};

#define UNKNOWN_IMPL \
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj){return _BaseQI(riid, ppvObj);} \
STDMETHOD_(ULONG, AddRef)(){return _BaseAddRef();} \
STDMETHOD_(ULONG, Release)(){return _BaseRelease();}

inline bool IsEqualIIDIgnoreData1(REFIID rguid1, REFIID rguid2)
{
   return (
      ((PLONG) &rguid1)[1] == ((PLONG) &rguid2)[1] &&
      ((PLONG) &rguid1)[2] == ((PLONG) &rguid2)[2] &&
      ((PLONG) &rguid1)[3] == ((PLONG) &rguid2)[3]);
}

inline bool FastIsEqualIID(REFIID rguid1, REFIID rguid2)
{
   return (
      ((PLONG) &rguid1)[0] == ((PLONG) &rguid2)[0] &&
      ((PLONG) &rguid1)[1] == ((PLONG) &rguid2)[1] &&
      ((PLONG) &rguid1)[2] == ((PLONG) &rguid2)[2] &&
      ((PLONG) &rguid1)[3] == ((PLONG) &rguid2)[3]);
}

#ifndef __PLACEMENT_NEW_INLINE
#define __PLACEMENT_NEW_INLINE
inline void *__cdecl operator new( size_t, void *_P) {return (_P); }
#if _MSC_VER > 1200
inline void *__cdecl operator new[]( size_t, void *_P) {return (_P); }
#endif
#endif

#include "VBoostTypes.h"

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__893CD0F1_19C4_11D3_ABA0_00C04F6BC74E__INCLUDED)
